package lib.scrren;

import java.awt.BufferCapabilities;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JWindow;

import lib.Config;
import lib.Utils;

/**
 * Look here for double buffered page flipping (DBPF :D):
 * http://www.exampledepot.com/egs/java.awt/screen_Flip.html
 */
public class Screen extends Thread {
	BufferStrategy strategy = null;
	private JWindow win = null;
	JFrame frame = null;
	DisplayAble display = null;
	boolean run = true;
	JFrame master = null;
	public static Screen instance;
	public boolean components;
	public JPanel content = new JPanel();
	static {
		instance = new Screen();
	}

	public static Screen getInstance() {
		if (instance == null)
			instance = new Screen();
		return instance;
	}

	public void setDisplay(DisplayAble display) {
		this.display = display;
	}

	public void setMaster(JFrame master) {
		if (master != null) {
			this.master = master;
			master.setFocusable(false);
			master.setVisible(false);
		}
	}

	public Screen() {

		// Determine if page flipping is supported
		GraphicsEnvironment ge = GraphicsEnvironment
				.getLocalGraphicsEnvironment();
		GraphicsDevice gd = ge.getDefaultScreenDevice();
		GraphicsConfiguration gc = gd.getDefaultConfiguration();
		BufferCapabilities bufCap = gc.getBufferCapabilities();
		boolean page = bufCap.isPageFlipping();

		if (page) {
			// Page flipping is supported
		} else {
			// Page flipping is not supported
		}

		// Create a window for full-screen mode
		frame = new JFrame(gd.getDefaultConfiguration());
		frame.setLayout(null);
		frame.setSize(Config.xRes, Config.yRes);
		content.setSize(frame.getSize());
		content.setOpaque(false);
		frame.add(content);
		win = new JWindow(frame);
		try {
			// Enter full-screen mode
			gd.setFullScreenWindow(win);
			// frame.setFocusable(false);
			frame.setVisible(true);
			win.setFocusable(false);
			// win.requestFocus();
			// win.requestFocusInWindow();
			win.setVisible(true);
			// Create the back buffer
			int numBuffers = 2; // Includes front buffer
			win.createBufferStrategy(numBuffers);
			strategy = win.getBufferStrategy();
			bufCap = strategy.getCapabilities();
			this.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void run() {
		double time;
		String debug = "";
		while (run) {
			if (display != null) {
				time = System.currentTimeMillis();
				try {
					// frame.requestFocus();
					Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
					g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
							RenderingHints.VALUE_ANTIALIAS_ON);
					g.fillRect(0, 0, 10000, 1000);
					debug = display.draw(g);
					if (components) {
						content.updateUI();
						content.paintComponents(g);
					}

					g.setColor(Color.GRAY);
					g
							.drawString(
									"Fps: "
											+ (int) (1d / ((System
													.currentTimeMillis() - time) / 1000d))
											+ "          " + debug, 20, 20);
					strategy.show();
					g.dispose();
				} catch (IllegalStateException e) {
				}
			} else {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}
		exit();
	}

	public void exit() {
		if (win != null && frame != null) {
			run = false;
			frame.dispose();
			strategy.dispose();
			win.dispose();
		}
		if (master != null) {
			master.setFocusable(true);
			master.setVisible(true);
		}
		GraphicsEnvironment.getLocalGraphicsEnvironment()
				.getDefaultScreenDevice().setFullScreenWindow(null);
		instance = null;
		System.exit(0);
	}

}
